package com.service.business.member.service.impl;

import com.service.business.base.service.CoinsPriceService;
import com.service.business.member.controller.rep.MemberAssetRep;
import com.service.business.member.controller.rep.MemberIncomeRep;
import com.service.business.member.controller.rep.MemberStorePageRep;
import com.service.business.member.service.MemberAssetService;
import com.service.business.member.service.MemberCacheService;
import com.service.business.member.service.MemberStoreService;
import com.service.business.order.service.OrderProductHrComboDetailsService;
import com.service.business.support.SessionUtil;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.MemberJAType;
import com.service.dao.mapper.JournalAccountMapper;
import com.service.dao.po.MemberCache;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <dl>
 * <dt>back-end</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2015</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019年09月24日</dd>
 * </dl>
 *
 * @author
 */
@Slf4j
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MemberAssetServiceImpl implements MemberAssetService {

    @Autowired
    private SessionUtil sessionUtil;
    @Autowired
    private CoinsPriceService coinsPriceService;
    @Autowired
    private MemberStoreService memberStoreService;
    @Autowired
    private MemberCacheService memberCacheService;
    @Autowired
    private JournalAccountMapper journalAccountMapper;
    @Autowired
    private OrderProductHrComboDetailsService orderProductHrComboDetailsService;


    @Override
    public MemberAssetRep memberAsset() {
        Integer userId = sessionUtil.getUser().getUserId();

        Map<String, BigDecimal> coinPriceMap = coinsPriceService.getStandardPrice2Map(Boolean.TRUE);
        AtomicReference<BigDecimal> totalAsset = new AtomicReference<>(BigDecimal.ZERO);
        List<MemberStorePageRep> storePageRepList = memberStoreService.listMemberStore(userId).stream().map(item -> {
            MemberStorePageRep pageRep = ModelMapperUtil.getStrictModelMapper().map(item, MemberStorePageRep.class);
            if (StringUtils.equals(pageRep.getCoinsName(), CoinsEnum.POINTS.getName())) {
                pageRep.setTotalConvert(pageRep.getNum());
                return pageRep;
            }
            if(StringUtils.equals(pageRep.getCoinsName(), CoinsEnum.FIL.getName())){
                BigDecimal totalPledgeNum = orderProductHrComboDetailsService.totalPledgeNumByMemberIdAndCoins(item.getMemberId(), item.getCoinsName());
                pageRep.setPledgeNum(totalPledgeNum);
            }
            if (coinPriceMap.containsKey(pageRep.getCoinsName())) {
                pageRep.setTotalConvert(pageRep.getNum().multiply(coinPriceMap.get(pageRep.getCoinsName())));
                totalAsset.set(totalAsset.get().add(pageRep.getTotalConvert()));
            } else {
                pageRep.setTotalConvert(pageRep.getNum());
                totalAsset.set(totalAsset.get().add(pageRep.getNum()));
            }
            return pageRep;
        }).collect(Collectors.toList());

        MemberIncomeRep incomeRep = getMemberAccumulatedIncome(userId);
        BigDecimal filStanderPrice = coinPriceMap.get(CoinsEnum.FIL.getName());
        MemberIncomeRep yesterdayIncome = getYesterdayIncome(userId);
        return MemberAssetRep.builder()
                .totalAsset(totalAsset.get())
                .storeList(storePageRepList)
                .yesterdayIncome(yesterdayIncome.getAwardIncome().add(yesterdayIncome.getMiningIncome().multiply(filStanderPrice)))
                .accumulatedIncome(incomeRep.getAwardIncome().add(filStanderPrice.multiply(incomeRep.getMiningIncome())))
                .storeFreezeStatus(sessionUtil.getUser().getStoreFreezeStatus())
                .build();
    }

    private MemberIncomeRep getYesterdayIncome(Integer memberId) {
        Date yesterday = DateUtils.addDays(new Date(), -1);

        return MemberIncomeRep.builder()
                .awardIncome(this.getSomedayAwardIncome(memberId, yesterday))
                .miningIncome(this.getSomedayMiningIncome(memberId, yesterday))
                .build();
    }

    /**
     * 获取累计收益
     *
     * @param memberId
     * @return
     */
    @Override
    public MemberIncomeRep getMemberAccumulatedIncome(Integer memberId) {
        MemberCache memberCache = memberCacheService.getMemberCache(memberId);

        return MemberIncomeRep.builder()
                .awardIncome(memberCacheService.getMemberTotalAward(memberCache))
                .miningIncome(memberCache.getHashRateAward()).build();
    }

    /**
     * 获取某一天会员收益
     *
     * @param memberId
     * @return
     */
    private BigDecimal getSomedayAwardIncome(Integer memberId, Date someday) {
        return journalAccountMapper.getSomedayIncome(memberId, MemberJAType.getAwardIncomeType(), DateFormatUtils.format(someday, "yyyy-MM-dd"));
    }

    /**
     * 获取某一天会员收益
     *
     * @param memberId
     * @return
     */
    private BigDecimal getSomedayMiningIncome(Integer memberId, Date someday) {
        return journalAccountMapper.getSomedayIncome(memberId, MemberJAType.getMiningIncomeType(), DateFormatUtils.format(someday, "yyyy-MM-dd"));
    }


}
